home *** CD-ROM | disk | FTP | other *** search
- #include <errno.h> /* obligatory includes */
- #include <signal.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <sys/wait.h>
- #include <sys/stat.h>
- #include <netinet/in.h>
- #include <netdb.h>
- #include <fcntl.h>
-
- #include <time.h>
-
- #include <sys/stat.h>
- #include <unistd.h>
-
- /* Log level constants */
- #define LOG_DEBUG 0
- #define LOG_MSG 1
- #define LOG_REQ 2
- #define LOG_ERR 3
-
- #define VERSION "Meredydd Luff's Surfboard/1.1.6 (UNIX/beta)"
-
- #define CGI_ENV_LEN 64
- /* ^^^^^^^^^^^ = max. number of environment variables for CGI script*/
-
- char hostname[1024]="";
-
- /* This can be overridden from the command line */
- char conffile[1024] = "/etc/surfboard/surfboard.conf";
-
- /* All of these can be overridden from the config file */
- char docroot[1024] = "/pub";
- char logfile[1024] = "/var/log/surfboard/httpd.log";
- char mimefile[1024] = "/etc/surfboard/mime.conf";
- char mime_default[512] = "text/plain";
- char dirindex[1024] = "index.html";
-
- int myport=80;
- int uid=99; /* "nobody" on my machine */
- int gid=99; /* "nogroup" for me */
-
- int log_threshold=LOG_MSG; /* By default, log everything bar debugs */
- int header_max=1024;
-
- void process(int, char *, int);
- void readconf(void);
- void log_msg(int level, char * msg);
-
- char * getextension(char *);
- void cgi_setenv(char **, char *, char *);
- void getmime(char *, char *, char *);
- void dumperror(int, int, char *);
- void mk_index(int, char *, char *, int);
- void fillout_header(char *);
- void add2header(char*, char *);
- char readstr(int, char *, int);
- void writestr(int, char *);
- void chomp(char *);
- int stripqmark(char *);
- int setupsock(void);
- void fireman(void);
-
- main(int argc, char * argv[])
- {
- int s, a;
-
- if(argc>1) { strcpy(conffile, argv[1]); }
-
- readconf();
-
- log_msg(LOG_MSG, "Surfboard started");
-
- if((s=setupsock())<0)
- {
- log_msg(LOG_ERR, "Could not open socket");
- perror("Could not open socket");
- return 1;
- }
-
- signal(SIGCHLD, fireman);
-
- if(fork()) { exit(0); }
-
- while(1)
- {
- int ns;
- while((ns=accept(s, NULL, NULL))<0);
- if(!fork()) {
- close(ns);
- } else {
- if(uid) { setuid(uid); }
- if(gid) { setgid(gid); }
- process(ns, docroot, s);
- exit(0);
- }
- }
- }
- /************************************************************************/
- void process(int s, char * docroot, int orgs)
- {
- char * http_header;
- char http_version[10]="NONE";
- int do_header=0;
- char rawreq[1024];
- char content_type[512];
- char handler[1024]="dump";
- char req[2048];
- char method[10];
- char buf[2048];
-
- int methodok=0;
-
- struct stat file_inf;
-
- log_msg(LOG_DEBUG, "Request received");
-
-
- http_header=(char *)malloc(header_max * sizeof(char));
- http_header[0]='\0';
-
- readstr(s, method, 10);
-
- if(!strcmp(method, "GET"))
- {
- methodok=1;
- }
-
- if(!methodok)
- {
- sprintf(buf, "Unknown method \"%s\", bailing out with a 400", method);
- log_msg(LOG_ERR, buf);
- add2header(http_header, "HTTP/1.1 400 Bad Request\r\n");
- fillout_header(http_header);
- add2header(http_header, "Content-type: text/html\r\n\r\n");
- if(do_header) { writestr(s, http_header); }
- dumperror(s, 400, "");
- exit(0);
- }
-
- if(readstr(s, rawreq, 1024)==' ')
- {
- char c=' ', oldc='\n';
-
- readstr(s, http_version, 10);
- do_header=1;
-
- /* Flush the browser options - perhaps I'll take some notice of them
- sometime ;-)
- */
- while(1)
- {
- while(read(s, &c, 1)<1);
- if(c=='\r') { continue; }
- if(c=='\n' && oldc=='\n') { break; }
- oldc=c;
- }
- } else {
- do_header=0;
- }
-
- sprintf(buf, "Asked for %s", rawreq);
- log_msg(LOG_DEBUG, buf);
-
- if(strstr(rawreq, "..") || strstr(rawreq, "`"))
- {
- log_msg(LOG_ERR, "Relative path and/or shell escape - ATTACK ATTEMPT");
- add2header(http_header, "HTTP/1.1 400 Bad Request\r\n");
- fillout_header(http_header);
- add2header(http_header, "Content-type: text/html\r\n\r\n");
- if(do_header) { writestr(s, http_header); }
- dumperror(s, 400, "");
- exit(0);
- }
-
- strcpy(req, docroot);
- strcat(req, rawreq);
- if(strstr(req, "?"))
- {
- char * p;
- p=(char *)strstr(req, "?");
- *p='\0';
- }
-
- errno=0;
-
- stat(req, &file_inf);
-
- if(errno==ENOENT)
- {
- add2header(http_header, "HTTP/1.1 404 Not Found\r\n");
- fillout_header(http_header);
- add2header(http_header, "Content-type: text/html\r\n\r\n");
- if(do_header) { writestr(s, http_header); }
- sprintf(buf, "%s %s %s 404", method, rawreq, http_version);
- log_msg(LOG_REQ, buf);
- dumperror(s, 404, rawreq);
- exit(0);
- }
- if(S_ISDIR(file_inf.st_mode))
- {
- log_msg(LOG_DEBUG, "Indexing directory");
-
- mk_index(s, req, rawreq, do_header);
- /* also handles redirect to put slashes on dir names*/
-
- sprintf(buf, "Finished indexing, now requesting %s", req);
- log_msg(LOG_DEBUG, buf);
- }
-
- log_msg(LOG_DEBUG, "Determining MIME type...");
-
- getmime(req, content_type, handler);
-
- sprintf(buf, "Determined MIME type: %s (action:%s)", content_type, handler);
- log_msg(LOG_DEBUG, buf);
-
- if(!strcmp(handler, "dump"))
- {
- int rdhandle;
-
- log_msg(LOG_DEBUG, "Dumping file");
- errno=0;
-
- rdhandle=open(req, O_RDONLY);
- switch(errno)
- {
- case(0) : { break; }
- default : {
- add2header(http_header, "HTTP/1.1 499 Unknown Error\r\n");
- fillout_header(http_header);
- add2header(http_header, "Content-type: text/html\r\n\r\n");
- if(do_header) { writestr(s, http_header); }
- sprintf(buf, "%s %s %s 499", method, rawreq, http_version);
- log_msg(LOG_REQ, buf);
- dumperror(s, 499, rawreq);
- exit(0);
- }
- }
-
- http_header[0]='\0';
- add2header(http_header, "HTTP/1.1 200 OK\r\n");
- fillout_header(http_header);
- add2header(http_header, "Content-type: ");
- add2header(http_header, content_type);
- add2header(http_header, "\r\n\r\n");
- if(do_header) { writestr(s, http_header); }
- sprintf(buf, "%s %s %s 200", method, rawreq, http_version);
- log_msg(LOG_REQ, buf);
- stat(req, &file_inf);
- while(file_inf.st_size>0)
- {
- int dlen;
- dlen=read(rdhandle, buf, 1024);
- file_inf.st_size-=dlen;
- write(s, buf, dlen);
- }
- close(rdhandle);
- log_msg(LOG_DEBUG, "File closed, going to the big exit statement in the sky...");
- }
-
- if(handler[0]=='/' || !strcmp(handler, "cgi") || !strcmp(handler, "cgi-nph"))
- {
- int qpos=0;
- char * cgienv[CGI_ENV_LEN];
- char path[1024];
-
- strcpy(path, req);
- for(qpos=strlen(path)-1; qpos>0; qpos--)
- {
- if(path[qpos]=='/') { break; }
- path[qpos]='\0';
- }
- chdir(path);
-
- log_msg(LOG_DEBUG, "Identified as CGI script/handler");
-
- if(handler[0]=='/') { stat(handler, &file_inf); }
-
- if(!(file_inf.st_mode&S_IXOTH))
- {
- http_header[0]='\0';
- if(do_header)
- {
- add2header(http_header, "HTTP/1.1 403 Forbidden\r\n");
- fillout_header(http_header);
- add2header(http_header, "Content-type: text/html\r\n\r\n");
- writestr(s, http_header);
- }
- sprintf(buf, "%s %s %s 403", method, rawreq, http_version);
- log_msg(LOG_REQ, buf);
- dumperror(s, 403, rawreq);
- exit(0);
- }
-
- if(!strcmp(handler, "cgi"))
- {
- log_msg(LOG_DEBUG, "Not NPH, building header");
- http_header[0]='\0';
- add2header(http_header, "HTTP/1.1 200 OK\r\n");
- fillout_header(http_header);
- writestr(s, http_header); /* Broken if HTTP/x.x not specified! */
- }
- close(1); /* stdout */
- log_msg(LOG_DEBUG, "stdout closed");
-
- if(dup(s)!=1)
- {
- log_msg(LOG_ERR, "CGI script stdout redirection failed");
- http_header[0]='\0';
- add2header(http_header, "HTTP/1.1 500 Internal Server Error\r\n");
- fillout_header(http_header);
- if(do_header) { writestr(s, http_header); }
- dumperror(s, 500, "");
- }
-
- log_msg(LOG_DEBUG, "Setting up environment variables");
-
- cgienv[0]=NULL;
-
- /* Got this list from the CGI 1.1 specification
- (http://hoohoo.ncsa.uiuc.edu/cgi/)
- */
- cgi_setenv(cgienv, "SERVER_SOFTWARE", VERSION);
- cgi_setenv(cgienv, "SERVER_NAME", hostname);
- cgi_setenv(cgienv, "GATEWAY_INTERFACE", "CGI/1.1");
- cgi_setenv(cgienv, "SERVER_PROTOCOL", http_version);
- sprintf(buf, "%d", myport);
- cgi_setenv(cgienv, "SERVER_PORT", buf);
- cgi_setenv(cgienv, "REQUEST_METHOD", method);
- /*
- Neither PATH_INFO nor PATH_TRANSLATED are set, as I haven't a clue
- what they are! Any help to m_luff@wincoll.ac.uk
- */
- log_msg(LOG_DEBUG, "Stripping arguments...");
- qpos=stripqmark(rawreq);
- cgi_setenv(cgienv, "SCRIPT_NAME", rawreq);
- log_msg(LOG_DEBUG, "Stripped arguments OK");
- /* cgi_setenv(cgienv, "REMOTE_ADDR", ); */ /* STORE IT */
- /* cgi_setenv(cgienv, "REMOTE_HOST", ); - Leaving unset */
- /* AUTH_TYPE is not set */
- /* REMOTE_USER is not set */
- /* REMOTE_IDENT is not set */
- /* CONTENT_TYPE is not set */
- /* CONTENT_LENGTH is not set */
-
- /* One day I'll put in HTTP_xxx from the client */
-
- if(handler[0]=='/')
- {
- log_msg(LOG_DEBUG, "Launching CGI handler");
- cgi_setenv(cgienv, "QUERY_STRING", rawreq+qpos);
- execle(handler, handler, req, NULL, cgienv);
- } else if(strstr(rawreq+qpos, "=") || *(rawreq+qpos)=='\0') {
- log_msg(LOG_DEBUG, "Query string");
- cgi_setenv(cgienv, "QUERY_STRING", rawreq+qpos);
- execle(req, req, NULL, cgienv);
- } else {
- log_msg(LOG_DEBUG, "Command-line option");
- execle(req, req, rawreq+qpos, NULL, cgienv);
- }
- log_msg(LOG_ERR, "execle() call returned!");
- perror("execle()");
- dup(2); /* stderr is copied onto the first free descriptor - stdout,
- in case something went wrong */
- }
-
- free(http_header);
- close(s);
- }
- /************************************************************************/
- void dumperror(int s, int num, char * req)
- {
- char buf[1024];
-
- switch(num)
- {
- case(400) : {
- writestr(s, "<HTML>\n<HEAD><TITLE>400 Bad Request</TITLE></HEAD>\n");
- writestr(s, "<BODY>\n<H1 ALIGN=CENTER>400 Bad Request</H1>\n");
- writestr(s, "<P ALIGN=CENTER><I>Your client sent an invalid request, ");
- writestr(s, "or one which the server cannot deal with.</I></P>\n");
- writestr(s, "<P ALIGN=RIGHT>" VERSION "</P>\n</BODY>\n</HTML>\n");
- close(s);
- break;
- }
-
- case(403) : {
- writestr(s, "<HTML>\n<HEAD><TITLE>403 Permission Denied</TITLE></HEAD>\n");
- writestr(s, "<BODY>\n<H1 ALIGN=CENTER>403 Permission Denied</H1>\n");
- writestr(s, "<P ALIGN=CENTER><I>You do not have permission to ");
- sprintf(buf, "access %s on this server</I></P>\n<P ALIGN=RIGHT>" VERSION
- "</P>\n</BODY>\n</HTML>\n", req);
- writestr(s, buf);
- close(s);
- break;
- }
-
- case(404) : {
- writestr(s, "<HTML>\n<HEAD><TITLE>404 Not Found</TITLE></HEAD>\n");
- writestr(s, "<BODY>\n<H1 ALIGN=CENTER>404 Not Found</H1>\n");
- writestr(s, "<P ALIGN=CENTER><I>The specified file was not ");
- writestr(s, "found</I></P>\n<P ALIGN=RIGHT>" VERSION
- "</P>\n</BODY>\n</HTML>\n");
- close(s);
- break;
- }
-
- case(499) : {
- writestr(s, "<HTML>\n<HEAD><TITLE>499 Unknown Error</TITLE></HEAD>\n");
- writestr(s, "<BODY>\n<H1 ALIGN=CENTER>499 Unknown Error</H1>\n");
- writestr(s, "<P ALIGN=CENTER><I>An error occurred while opening ");
- writestr(s, "this file. What it is, I do not know! Contact ");
- writestr(s, "the webmaster.</I></P>\n<P ALIGN=RIGHT>" VERSION
- "</P>\n</BODY>\n</HTML>\n");
- close(s);
- break;
- }
-
- case(500) : {
- writestr(s, "<HTML>\n<HEAD><TITLE>500 Internal Server Error</TITLE></HEAD>\n");
- writestr(s, "<BODY>\n<H1 ALIGN=CENTER>500 Internal Server Error</H1>\n");
- writestr(s, "<P ALIGN=CENTER><I>Something went wrong inside"
- " the server. Perhaps a CGI script went awry, or something "
- "in the bowels of the httpd is broken. Get your admin to check the "
- "logfile for error messages.</I></P>\n<P ALIGN=RIGHT>" VERSION
- "</P>\n</BODY>\n</HTML>\n");
- close(s);
- break;
- }
-
- default : {
- sprintf(buf, "<HTML>\n<HEAD><TITLE>%d - Unhandled HTTP Error"
- "</TITLE></HEAD>\n<BODY><H1 ALIGN=CENTER>%d - Unhandled HTTP "
- "Error</H1>\n<P ALIGN=CENTER><I>This is a bug in the web server. "
- "The server has trapped an error and knows what went wrong, but "
- "the author has forgotten to write an explanation of this "
- "error code. Mail Meredydd Luff (at <A "
- "HREF=mailto:m_luff@wincoll.ac.uk>m_luff@wincoll.ac.uk</A>) "
- "and tell him what happened.</I></P>\n<P ALIGN=RIGHT>" VERSION
- "</P>\n</BODY>\n</HTML>\n", num, num);
- writestr(s, buf);
- close(s);
- break;
- }
- }
- }
- /************************************************************************/
- void cgi_setenv(char ** env, char * name, char * value)
- {
- int a=0;
- while(env[a]!=NULL) { a++; }
- if(a==CGI_ENV_LEN-1)
- {
- char buf[1024];
- sprintf(buf, "CGI environment full - cannot add %s=%s", name, value);
- log_msg(LOG_ERR, buf);
- return;
- }
- env[a+1]=NULL;
- env[a]=(char *)malloc((strlen(name)+strlen(value)+64)*sizeof(char));
- strcpy(env[a], name);
- strcat(env[a], "=");
- strcat(env[a], value);
- }
- /************************************************************************/
- void redirect(int s, char * from, char * to, int do_header)
- {
- char buf[4096];
- char * http_header;
- http_header=(char *)malloc(header_max*sizeof(char));
-
- http_header[0]='\0';
- add2header(http_header, "HTTP/1.1 301 Moved Permanently\r\n");
- fillout_header(http_header);
- add2header(http_header, "Location: ");
- add2header(http_header, to);
- add2header(http_header, "\r\n\r\n");
- if(do_header) { writestr(s, http_header); }
- sprintf(buf, "<HTML>\n<HEAD><TITLE>301 Moved Permanently</TITLE>"
- "</HEAD>\n<BODY><H1 ALIGN=CENTER>301 Moved Permanently</H1>\n"
- "<P ALIGN=CENTER><I>The URL %s has moved to <A HREF=\"%s\">%s</A>"
- "</I></P>\n<P ALIGN=RIGHT>" VERSION "</P>\n</BODY>\n</HTML>\n",
- from, to, to);
- writestr(s, buf);
- free(http_header);
- }
- /************************************************************************/
- void mk_index(int s, char * req, char * rawreq, int do_header)
- {
- char buf[4096];
- int pos=0;
- int p=0, do404=0;
-
- struct stat file_inf;
-
- if(req[strlen(req)-1]!='/')
- {
- char http_header[1024]="";
- char corrected[1024];
-
- strcpy(corrected, rawreq);
- strcat(corrected, "/");
- redirect(s, rawreq, corrected, do_header);
- exit(0);
- }
-
- errno=0;
-
- log_msg(LOG_DEBUG, "Trying:");
-
- do
- {
- strcpy(buf, req);
-
- p=pos;
- while(!(dirindex[p]=='\0' || isspace(dirindex[p]))) { p++; }
-
- if(dirindex[p]=='\0') { do404=1; }
- dirindex[p]='\0';
- if(dirindex[pos]=='/')
- { strcpy(buf, dirindex+pos); } else { strcat(buf, dirindex+pos); }
-
- log_msg(LOG_DEBUG, buf);
-
- errno=0;
- stat(buf, &file_inf);
-
- if(S_ISDIR(file_inf.st_mode)) { errno=ENOENT; }
-
- pos=p+1;
- } while(errno==ENOENT && !do404);
-
- if(do404 && errno==ENOENT)
- {
- char * http_header;
- http_header=(char *)malloc(header_max*sizeof(char));
- http_header[0]='\0';
- add2header(http_header, "HTTP/1.1 404 Not Found\r\n");
- fillout_header(http_header);
- add2header(http_header, "Content-type: text/html\r\n\r\n");
- if(do_header) { writestr(s, http_header); }
- dumperror(s, 404, rawreq);
- free(http_header);
- exit(0);
- } else {
- strcpy(req, buf);
- }
-
- }
- /************************************************************************/
- void fillout_header(char * header)
- {
- add2header(header, "Server: " VERSION "\r\n");
- add2header(header, "Connection: close\r\n");
- }
- /************************************************************************/
- void getmime(char * req, char * content_type, char * handler)
- {
- FILE * mime;
- char buf[4096];
-
- strcpy(content_type, mime_default);
- strcpy(handler, "dump");
-
- if((mime=fopen(mimefile, "r"))==NULL)
- {
- sprintf(buf, "Could not open MIME config file \"%s\", using default "
- "content type %s\n", mimefile, mime_default);
- log_msg(LOG_ERR, buf);
- strcpy(content_type, mime_default);
- } else {
- char thisext[512];
- char thistype[512];
- char thishandler[1024];
- char myext[512];
-
- strcpy(myext, getextension(req));
- while(!feof(mime))
- {
- fscanf(mime, " %s", thisext);
- if(thisext[0]=='#') { while(getc(mime)!='\n'); continue; }
- fscanf(mime, " %s ", thistype);
- fgets(thishandler, 1024, mime);
- chomp(thishandler);
- if(!strcmp(myext, thisext))
- { strcpy(content_type, thistype); strcpy(handler, thishandler); break; }
- }
- fclose(mime);
- }
- }
- /************************************************************************/
- void add2header(char * header, char * line)
- {
- if(strlen(header)+strlen(line)+1>header_max)
- {
- log_msg(LOG_ERR, "Header exceeded max length, line ignored");
- } else {
- strcat(header, line);
- }
- }
- /************************************************************************/
- void readconf(void)
- {
- FILE * conf;
- char cmd[512];
- char buf[1600];
-
- sprintf(buf, "Reading config from file \"%s\"", conffile);
- log_msg(LOG_DEBUG, buf);
-
- if((conf=fopen(conffile, "r"))==NULL)
- {
- sprintf(buf, "Could not open config file \"%s\"", conffile);
- log_msg(LOG_ERR, buf);
- fprintf(stderr, "%s\n", buf);
- exit(1);
- }
-
- while(1)
- {
- fscanf(conf, " %s ", cmd);
- if(feof(conf)) { break; }
- if(cmd[0]=='#') { while(getc(conf)!='\n'); continue; }
-
- if(!strcmp(cmd, "Port"))
- {
- fscanf(conf, " %d", &myport);
- continue;
- }
-
- if(!strcmp(cmd, "DocRoot"))
- {
- fscanf(conf, " %s", docroot);
- continue;
- }
-
- if(!strcmp(cmd, "LogFile"))
- {
- fscanf(conf, " %s", logfile);
- continue;
- }
-
- if(!strcmp(cmd, "LogThreshold"))
- {
- fscanf(conf, " %d", &log_threshold);
- continue;
- }
-
- if(!strcmp(cmd, "MimeFile"))
- {
- fscanf(conf, " %s", mimefile);
- continue;
- }
-
- if(!strcmp(cmd, "DefaultMime"))
- {
- fscanf(conf, " %s", mime_default);
- continue;
- }
-
- if(!strcmp(cmd, "SetUID"))
- {
- fscanf(conf, " %d", &uid);
- continue;
- }
-
- if(!strcmp(cmd, "SetGID"))
- {
- fscanf(conf, " %d", &gid);
- continue;
- }
-
- if(!strcmp(cmd, "DirIndex"))
- {
- fgets(dirindex, 1024, conf);
- chomp(dirindex);
- continue;
- }
-
- fprintf(stderr, "Surfboard - Invalid config option \"%s\"\n", cmd);
- fclose(conf);
- exit(1);
- }
- fclose(conf);
- log_msg(LOG_DEBUG, "Finished reading config file");
- }
- /************************************************************************/
- void log_msg(int level, char * str)
- {
- if(level>=log_threshold)
- {
- if(!strcmp(logfile, "-"))
- {
- fprintf(stderr, "Surfboard - Log level %d: %s\n", level, str);
- } else {
- FILE * logfileptr;
- int a;
- time_t now;
-
- time(&now);
-
- for(a=0; a<5; a++)
- {
- logfileptr=fopen(logfile, "a");
- if(logfileptr==NULL) { continue; }
- fprintf(logfileptr, "%d %s%s\n", level, ctime(&now), str);
- fclose(logfileptr);
- return;
- }
- printf("Surfboard - Cannot open logfile!\a\n");
- perror("Surfboard - Cannot open logfile!\a");
- printf("Surfboard - Log level %d: %s\n", level, str);
- }
- }
- }
- /************************************************************************/
- char * getextension(char * s)
- {
- char scopy[1024];
- char * retval;
-
- strcpy(scopy, s);
- retval=strstr(scopy, "?");
- if(retval==NULL)
- { retval=scopy+strlen(s); } else { *retval='\0'; }
-
- while(1)
- {
- retval--;
- if(*retval=='.')
- { log_msg(LOG_DEBUG, retval+1);
- return (retval+1); }
- if(retval==scopy) { return s; }
- }
- }
- /************************************************************************/
- void writestr(int s, char * buf)
- {
- write(s, buf, strlen(buf));
- }
- /************************************************************************/
- void chomp(char * s)
- {
- if(s[0]=='\0') { return; }
- if(s[strlen(s)-1]=='\n') { s[strlen(s)-1]='\0'; }
- }
- /************************************************************************/
- int stripqmark(char * s)
- {
- int pos=0;
-
- do
- {
- if(s[pos]=='?') { s[pos]='\0'; return pos+1; }
- pos++;
- } while(s[pos]!='\0');
- return pos;
- }
- /************************************************************************/
- char readstr(int s, char * buf, int maxlen)
- {
- char c;
- int pos=0;
-
- while(1)
- {
- while(read(s, &c, 1)<1);
- if(c=='\r') { continue; } /* There's a \n coming... */
- if(isspace(c) || pos==maxlen-1) { buf[pos]='\0'; return c; }
- buf[pos]=c;
- pos++;
- }
- }
- /************************************************************************/
- int setupsock(void)
- {
- int s;
- struct sockaddr_in myopen;
- struct hostent *hp;
-
- memset(&myopen, 0, sizeof(struct sockaddr_in)); /* clear my address */
- gethostname(hostname, 1024); /* who are we? (also
- store for later) */
- hp= gethostbyname(hostname); /* get our address info */
- if (hp == NULL) /* we don't exist !? */
- return(-1);
- myopen.sin_family= hp->h_addrtype; /* this is our host address */
- myopen.sin_port= htons(myport); /* this is our port number */
- if ((s= socket(AF_INET, SOCK_STREAM, 0)) < 0) /* create socket */
- return(-1);
- if (bind(s,(struct sockaddr *)&myopen,sizeof(struct sockaddr_in)) < 0) {
- close(s);
- return(-1); /* bind address to socket */
- }
- listen(s, 3); /* max # of queued connects */
- return(s);
- }
- /*************************************************************************/
- /* Fireman - anti-zombie code. Greek to me, but it works ;-) */
- void fireman(void)
- {
- while (waitpid(-1, NULL, WNOHANG) > 0);
- }
-